class Solution {
    public boolean isNumber(String s) {
        Map[] map = {
            //0前面是刚开始的空格,后面可以跟空格,空白后面的小数点,整数,正负号
            new HashMap() {{put(' ',0);put('.',4);put('d',2);put('s',1);}},
            //1前面是正负号,后面能跟整数,前面没有数的小数点
            new HashMap() {{put('d',2);put('.',4);}},
            //2前面小数点之前的数,后面能跟整数,e,数字后面的小数点,结尾空格
            new HashMap(){{put('d',2);put('e',5);put('.',3);put(' ',8);}},
            //3前面是数字后面的小数点,或者小数点之后的数,后面能跟小数点之后的数,e,结尾空格
            new HashMap() {{put('d',3);put('e',5);put(' ',8);}},
            //4前面是空白后面的小数点,后面能跟小数点之后的数
            new HashMap() {{put('d',3);}},
            //5前面是e,后面可以是整数,e后面的正负号
            new HashMap() {{put('d',6);put('s',7);}},
            //6前面是e后面的数字,能跟一个整数和结尾空格
            new HashMap() {{put('d',6);put(' ',8);}},
            //7前面是e后面的正负号,后面只能跟一个整数
            new HashMap() {{put('d',6);}},
            //8前面是结尾空格,后面只能跟结尾空格
            new HashMap() {{put(' ',8);}}
        };

        char t;
        int p = 0;
        for(char ret : s.toCharArray()) {
            if('0' <= ret && '9' >= ret) {
                t = 'd';
            }else if('+' == ret || '-' == ret) {
                t = 's';
            }else if('e' == ret || 'E' == ret) {
                t = 'e';
            }else if (' ' == ret || '.' == ret){
                t = ret;
            }else {
                t = '?';
            }
            if(!map[p].containsKey(t)) {
                return false;
            }
            p = (int)map[p].get(t);
        }
        return p == 2|| p == 3|| p == 6|| p==8;
    }
}